package com.ddpt.permission.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lh.center.common.base.BizEntity;
import com.lh.center.common.base.BizServiceImpl;
import com.lh.center.common.dto.IdDto;
import com.lh.center.common.dto.IdExtDto;
import com.lh.center.common.exception.CommonException;
import com.lh.center.common.goods.BaseGoodsEntity;
import com.lh.center.common.util.AssertUtil;
import com.lh.center.permission.api.entity.StoreAdminUser;
import com.lh.center.permission.api.enums.StoreUserStatusEnums;
import com.lh.center.permission.api.request.PageStoreUserReq;
import com.lh.center.permission.api.request.StoreListRequest;
import com.lh.center.permission.api.request.UpdateStoreUserPasswordReq;
import com.lh.center.permission.api.response.PageStoreUserRes;
import com.lh.center.permission.mapper.StoreAdminUserMapper;
import com.lh.center.permission.service.StoreAdminUserService;
import com.lh.center.reach.api.dubbo.DubboApiHandlerService;
import com.lh.center.reach.api.dubbo.DubboExternalMerchantConfigService;
import com.lh.center.reach.api.dubbo.DubboSystemMerchantConfigService;
import com.lh.center.reach.api.entity.ExternalMerchantConfigEntity;
import com.lh.center.reach.api.external.enums.ExternalApiTypeEnum;
import com.lh.center.store.api.dubbo.DubboProductService;
import com.lh.center.store.api.dubbo.DubboStoreService;
import com.lh.center.store.api.entity.StoreBusinessEntity;
import com.lh.center.store.api.entity.StoreGoodsEntity;
import com.lh.center.store.api.vo.CountStoreGoodsQueryVo;
import com.lh.center.store.api.vo.CountStoreGoodsVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 商家表 服务实现类
 * </p>
 *
 * @author czy
 * @since 2022-04-13
 */
@Slf4j
@Service
public class StoreAdminUserServiceImpl extends BizServiceImpl<StoreAdminUserMapper, StoreAdminUser> implements StoreAdminUserService {

    @DubboReference
    private DubboProductService dubboProductService;

    @DubboReference
    private DubboSystemMerchantConfigService dubboSystemMerchantConfigService;

    @DubboReference
    private DubboApiHandlerService dubboApiHandlerService;

    @DubboReference
    private DubboExternalMerchantConfigService dubboExternalMerchantConfigService;

    @DubboReference
    private DubboStoreService dubboStoreService;

    @Resource
    private StoreAdminUserMapper storeAdminUserMapper;

    @Override
    public StoreAdminUser createStoreUser(StoreAdminUser storeAdminUser) {

        List<StoreAdminUser> nameList = list(Wrappers.lambdaQuery(StoreAdminUser.class)
                .eq(StoreAdminUser::getStoreName, storeAdminUser.getStoreName()));

        List<StoreAdminUser> userList = list(Wrappers.lambdaQuery(StoreAdminUser.class)
                .eq(StoreAdminUser::getUserName, storeAdminUser.getUserName()));

        if (!CollectionUtils.isEmpty(nameList)
                || !CollectionUtils.isEmpty(userList)) {
            throw new CommonException("用户名或商家名不能重复");
        }

        String password = storeAdminUser.getPassword();
        String showName = storeAdminUser.getShowName();
        if (StringUtils.isNotBlank(password)) {
            storeAdminUser.setPassword(DigestUtil.md5Hex(password));
        } else {
            //若没有设置密码，统一设置为123456
            storeAdminUser.setPassword(DigestUtil.md5Hex("123456"));
        }
        /*if (Objects.isNull(storeAdminUser.getId())){
            storeAdminUser.setStatus(StoreUserStatusEnums.AVAILABLE.getCode());
        }*/
        saveOrUpdate(storeAdminUser);

        //设置商家appId等信息
        dubboSystemMerchantConfigService.createStoreConfig(storeAdminUser.getMerchantId(), storeAdminUser.getId(), storeAdminUser.getSecretType());
        //设置商家可访问的开放接口权限
        dubboApiHandlerService.bindStoreAll(storeAdminUser.getId());

        return storeAdminUser;
    }

    @Override
    public void updateStoreUser(StoreAdminUser storeAdminUser) {

        StoreAdminUser existNameStore = this.getOne(Wrappers.lambdaQuery(StoreAdminUser.class)
                .eq(StoreAdminUser::getStoreName, storeAdminUser.getStoreName())
                .eq(StoreAdminUser::getMerchantId, storeAdminUser.getMerchantId())
        );
        AssertUtil.isTrue(null != existNameStore && !existNameStore.getId().equals(storeAdminUser.getId()), "商家名称重复");

        saveOrUpdate(storeAdminUser);
    }

    @Override
    public StoreAdminUser getStoreById(IdDto idDto) {
        StoreAdminUser storeAdminUser = getById(idDto.getId());
        AssertUtil.isNull(storeAdminUser, "商家不存在");
        storeAdminUser.setPassword(null);
        StoreBusinessEntity store = dubboStoreService.getByStoreUserId(storeAdminUser.getId());
        storeAdminUser.setConfigId(store.getConfigId());
        storeAdminUser.setPhone(store.getPhone());
        storeAdminUser.setDeductStatus(store.getDeductStatus());
        storeAdminUser.setDeductCheckStatus(store.getDeductCheckStatus());
        storeAdminUser.setGoodsCheck(store.getGoodsCheck());
        return storeAdminUser;
    }

    @Override
    public Page<PageStoreUserRes> getPageUser(PageStoreUserReq pageStoreUserReq) {
        Long insId = pageStoreUserReq.getInsId();
        String showName = pageStoreUserReq.getShowName();
        Integer status = pageStoreUserReq.getStatus();
        Integer currentPage = pageStoreUserReq.getCurrentPage();
        Integer showCount = pageStoreUserReq.getShowCount();
        Long merchantId = pageStoreUserReq.getMerchantId();
        String storeName = pageStoreUserReq.getStoreName();
        Page<StoreAdminUser> page = new Page<>(currentPage, showCount);
        Page<StoreAdminUser> userPage = page(page, Wrappers.lambdaQuery(StoreAdminUser.class)
                .eq(Objects.nonNull(insId), StoreAdminUser::getInsId, insId)
                .eq(BizEntity::getMerchantId, merchantId)
                .eq(Objects.nonNull(status), StoreAdminUser::getStatus, status)
                .like(StringUtils.isNotBlank(showName), StoreAdminUser::getShowName, showName)
                .like(StringUtils.isNotBlank(storeName), StoreAdminUser::getStoreName, storeName)
                .orderByDesc(BizEntity::getCreateTime));
        List<StoreAdminUser> records = userPage.getRecords();

        Page<PageStoreUserRes> resPage = new Page<>();
        resPage.setTotal(userPage.getTotal());
        resPage.setSize(userPage.getSize());
        resPage.setCurrent(userPage.getCurrent());
        if (CollectionUtils.isEmpty(records)) {
            resPage.setRecords(new ArrayList<>());
            return resPage;

        }

        List<PageStoreUserRes> list = new ArrayList<>();
        Set<Long> idSet = records.stream().map(BizEntity::getId).collect(Collectors.toSet());
        log.info("========================>查询商家商品开始:{}", System.currentTimeMillis());
        List<StoreGoodsEntity> storeGoodsEntities = dubboProductService.getAllByMerchantId(merchantId);
        log.info("========================>查询商家商品结束:{}", System.currentTimeMillis());
        Map<Long, List<StoreGoodsEntity>> listMap = storeGoodsEntities.stream().collect(Collectors.groupingBy(BaseGoodsEntity::getStoreId));
        for (StoreAdminUser record : records) {
            //计算商品数量
            record.setPassword(null);
            PageStoreUserRes pageStoreUserRes = new PageStoreUserRes();
            BeanUtils.copyProperties(record, pageStoreUserRes);
            List<StoreGoodsEntity> goodsEntities = listMap.get(record.getId());
            if (CollectionUtils.isEmpty(goodsEntities)) {
                pageStoreUserRes.setNumber(0);
            } else {
                pageStoreUserRes.setNumber(listMap.get(record.getId()).size());
            }
            list.add(pageStoreUserRes);
        }
        resPage.setRecords(list);
        return resPage;
    }

    @Override
    public Page<PageStoreUserRes> getStorePage(PageStoreUserReq req) {

        // 商家用户数据
        Page<StoreAdminUser> userPage = page(req.toMp(), Wrappers.lambdaQuery(StoreAdminUser.class)
                .eq(BizEntity::getMerchantId, req.getMerchantId())
                .eq(Objects.nonNull(req.getStatus()), StoreAdminUser::getStatus, req.getStatus())
                .like(StringUtils.isNotBlank(req.getShowName()), StoreAdminUser::getShowName, req.getShowName())
                .like(StringUtils.isNotBlank(req.getStoreName()), StoreAdminUser::getStoreName, req.getStoreName())
                .orderByDesc(BizEntity::getCreateTime));

        if (null == userPage || CollectionUtils.isEmpty(userPage.getRecords())) return new Page<>();

        Page<PageStoreUserRes> resPage = new Page<>();
        BeanUtils.copyProperties(userPage, resPage);

        // 商家用户id集合
        Set<Long> storeUserIds = userPage.getRecords().stream().map(StoreAdminUser::getId).collect(Collectors.toSet());

        // 获取商家表数据
        List<StoreBusinessEntity> stores = dubboStoreService.getByIds(storeUserIds);
        List<Long> storeIds = stores.stream().map(StoreBusinessEntity::getId).collect(Collectors.toList());
        Map<Long, StoreBusinessEntity> storeMap = stores.stream()
                .collect(Collectors.toMap(StoreBusinessEntity::getStoreUserId, Function.identity()));

        Set<Long> configIds = stores.stream().map(StoreBusinessEntity::getConfigId)
                .filter(Objects::nonNull).collect(Collectors.toSet());
        // 供应商配置
        Map<Long, String> configMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(configIds)){
            configMap.putAll(dubboExternalMerchantConfigService.getNameByIds(configIds));
        }

        // 获取商家商品统计数据
        CountStoreGoodsQueryVo queryVo = new CountStoreGoodsQueryVo();
        queryVo.setStoreIds(storeIds);
        List<CountStoreGoodsVo> countStoreGoods = dubboStoreService.countStoreGoodsNums(queryVo);
        Map<Long, Integer> storeGoodsMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(countStoreGoods)) {
            storeGoodsMap = countStoreGoods.stream()
                    .collect(Collectors.toMap(CountStoreGoodsVo::getStoreId, CountStoreGoodsVo::getCount));
        }

        PageStoreUserRes res;
        List<PageStoreUserRes> records = new ArrayList<>();
        for (StoreAdminUser record : userPage.getRecords()) {
            res = new PageStoreUserRes();
            BeanUtils.copyProperties(record, res);
            Long id = record.getId();
            if (storeMap.containsKey(id)) {
                StoreBusinessEntity store = storeMap.get(id);
                Long storeId = store.getId();
                res.setConfigId(store.getConfigId());
                res.setNumber(storeGoodsMap.getOrDefault(storeId, 0));
                res.setGoodsCheck(store.getGoodsCheck());
                if (null != store.getConfigId()){
                    res.setConfigName(configMap.get(store.getConfigId()));
                }
            }
            records.add(res);
        }
        resPage.setRecords(records);
        return resPage;
    }

    @Override
    public void deleteStoreUser(IdDto idDto) {
        //限制条件
        StoreAdminUser storeAdminUser = this.getById(idDto.getId());
        AssertUtil.isNull(storeAdminUser, "商家不存在");
        StoreBusinessEntity store = dubboStoreService.getByStoreUserId(storeAdminUser.getId());
        AssertUtil.isNull(store, "商家不存在");

        if (storeAdminUser.getMerchantId() == 0L || store.getMerchantId() == 0L){
            // 默认商家的默认平台
            if (null != store.getConfigId()){
                AssertUtil.isTrue(dubboExternalMerchantConfigService.getDefaultConfigUseCount(store.getConfigId()) > 0, "商家已授权商户,暂不支持删除");
            }
        }

        //删除
        removeById(idDto.getId());
        dubboStoreService.deleteStore(IdDto.builder(store.getId()));
    }

    @Override
    public Integer updateStatus(IdExtDto idDto) {
        StoreAdminUser storeAdminUser = getById(idDto.getId());
        Assert.notNull(storeAdminUser, "商家不存在");
        Integer status = storeAdminUser.getStatus();
        if (status.equals(StoreUserStatusEnums.UNAVAILABLE.getCode())) {
            storeAdminUser.setStatus(StoreUserStatusEnums.AVAILABLE.getCode());
            saveOrUpdate(storeAdminUser);
        } else if (status.equals(StoreUserStatusEnums.AVAILABLE.getCode())) {
            storeAdminUser.setStatus(StoreUserStatusEnums.UNAVAILABLE.getCode());
            saveOrUpdate(storeAdminUser);
        }
        return storeAdminUser.getStatus();
    }

    @Override
    public void updatePassword(UpdateStoreUserPasswordReq updateStoreUserPasswordDot) {
        //AssertUtil.isEmpty(updateStoreUserPasswordDot.getOldPassword(), "旧密码不能为空");
        AssertUtil.isEmpty(updateStoreUserPasswordDot.getPassword(), "新密码不能为空");
        StoreAdminUser storeAdminUser = storeAdminUserMapper.selectById(updateStoreUserPasswordDot.getId());
        //AssertUtil.isTrue(!storeAdminUser.getPassword().equals(DigestUtil.md5Hex(updateStoreUserPasswordDot.getOldPassword())), "旧密码错误");
        storeAdminUser.setPassword(DigestUtil.md5Hex(updateStoreUserPasswordDot.getPassword()));
        updateById(storeAdminUser);
    }

    @Override
    public void bindWx(Long id, String openId) {
        StoreAdminUser user = getById(id);
        user.setWxOpenId(openId);
        updateById(user);
    }

    @Override
    public void unBindWx(Long id) {
        LambdaUpdateWrapper<StoreAdminUser> wrapper = Wrappers.lambdaUpdate(StoreAdminUser.class).eq(StoreAdminUser::getId, id).set(StoreAdminUser::getWxOpenId, null);
        update(wrapper);
    }

    @Override
    public List<StoreAdminUser> getDefaultStores(StoreListRequest req) {

        // 查看该商家是否存在默认供应商平台
        List<ExternalMerchantConfigEntity> supplierConfigs = dubboExternalMerchantConfigService
                .getMerchantDefaultConfig(req.getMerchantId(), ExternalApiTypeEnum.supplier.name());

        if (CollectionUtils.isEmpty(supplierConfigs)) return new ArrayList<>();

        // 默认平台对应的商家
        Set<Long> defaultConfigIds = supplierConfigs.stream().map(ExternalMerchantConfigEntity::getParentId)
                .collect(Collectors.toSet());
        List<StoreBusinessEntity> stores = dubboStoreService.getByConfigIds(defaultConfigIds);

        if (CollectionUtils.isEmpty(stores)) return new ArrayList<>();

        Set<Long> storeUserIds = stores.stream().map(StoreBusinessEntity::getStoreUserId).collect(Collectors.toSet());
        return this.list(Wrappers.lambdaQuery(StoreAdminUser.class)
                .in(StoreAdminUser::getId, storeUserIds)
                .eq(StoreAdminUser::getStatus, 1)
        );
    }


}
